using System;
using Gtk;
using TwitterFx;
using System.Collections.Generic;
using System.Threading;
using System.Timers;
using NLog;

namespace TwitterFx {
	
	public partial class MainWindow: Gtk.Window
	{
		private System.Timers.Timer tmr = new System.Timers.Timer(600000);
		private Gtk.TreeViewColumn iconColumn = null;
		private Gtk.TreeViewColumn textColumn = null;
		private Gtk.CellRendererPixbuf iconCell = null;
		private Gtk.CellRendererText textCell = null;
		private Gtk.ListStore entryListStore = null;
		private TwitterClient tc = null;
		
		private uint STATUS_UPDATING = 1;
		private uint STATUS_SENDING = 2;
		private StatusIcon trayIcon;
		
		private static Logger log = LogManager.GetCurrentClassLogger();
		private TwitterFxConfig config = TwitterFxConfig.GetTwitterFxConfig();
				
		public MainWindow (): base (Gtk.WindowType.Toplevel)
		{
			Build ();
			BuildTree();
			
			int[] windowStatus = config.windowStatus;
			this.Move(windowStatus[0], windowStatus[1]);
			
			if (windowStatus[2] > 0 && windowStatus[3] > 0)
			{
				this.Resize(windowStatus[2], windowStatus[3]);
			}
			
			this.DefaultWidth = config.windowStatus[2];
			this.DefaultHeight = config.windowStatus[3];
						
			this.trayIcon = new StatusIcon(Gdk.Pixbuf.LoadFromResource("TwitterDefault.png"));
			trayIcon.Visible = true;
			trayIcon.Activate += delegate { this.Visible = !this.Visible; };
			trayIcon.PopupMenu += OnTrayIconPopup;
			trayIcon.Tooltip = "TweetsFX";
				
			log.Info("Entering application.");
						
			tc = new TwitterClient();
            tc.UserName = "erangaj2";
            tc.Password = "erangaj79828";
			
			StartFillEntries();

			tmr.Elapsed += new ElapsedEventHandler(TimerElapsed);
			tmr.Enabled = true;
		}
		
		public void BuildTree() 
		{
			iconColumn = new Gtk.TreeViewColumn ();
			iconColumn.Title = "Icon";
			iconCell = new Gtk.CellRendererPixbuf ();
			iconColumn.PackStart (iconCell, true);
	 
			textColumn = new Gtk.TreeViewColumn ();
			textColumn.Title = "Text";
			textCell = new Gtk.CellRendererText ();
			textColumn.PackStart (textCell, true);
			textCell.WrapMode = Pango.WrapMode.WordChar;
			
			entryListStore = new Gtk.ListStore (typeof(Entry));
			
			iconColumn.SetCellDataFunc (iconCell, new Gtk.TreeCellDataFunc (RenderEntryIcon));
			textColumn.SetCellDataFunc (textCell, new Gtk.TreeCellDataFunc (RenderEntryText));
 
			this.mainTree.Model = entryListStore;
			
			mainTree.AppendColumn(iconColumn);
			mainTree.AppendColumn(textColumn);
		}
		
		private void OnTrayIconPopup (object o, EventArgs args)
		{
			Menu popupMenu = new Menu();
			ImageMenuItem menuItemQuit = new ImageMenuItem ("Quit");
			Gtk.Image appimg = new Gtk.Image(Stock.Quit, IconSize.Menu);
			menuItemQuit.Image = appimg;
			popupMenu.Add(menuItemQuit);

			menuItemQuit.Activated += delegate { Application.Quit(); };
			
			popupMenu.ShowAll();
			popupMenu.Popup();
		}
		
		protected void OnDeleteEvent (object sender, DeleteEventArgs a)
		{
			Quit ();
			a.RetVal = true;
		}
		
	    public void TimerElapsed(object sender, ElapsedEventArgs e)
    	{
			StartFillEntries();
    	}

	
		protected virtual void OnBtnPostClicked (object sender, System.EventArgs e)
		{
			StartPosting();
		}

		private void StartPosting()
		{
			this.statusbar.Pop(STATUS_SENDING);
			this.statusbar.Push(STATUS_SENDING, "Sending...");
			this.txtPost.Editable = false;
			ThreadStart job = new ThreadStart(this.DoPost);
	        Thread thread = new Thread(job);
			thread.IsBackground = true;
	        thread.Start();
		}
		
		protected void DoPost()
		{
			try
			{
				tc.Post(this.txtPost.Buffer.Text);
				this.statusbar.Pop(STATUS_SENDING);
				StartFillEntries();
			}
			catch (System.Net.WebException e)
			{
				this.statusbar.Pop(STATUS_SENDING);
				this.statusbar.Push(STATUS_SENDING, "Error while sending status");
				log.Error("Error while sending status", e);
			}
			
			this.txtPost.Buffer.Text = "";
			this.txtPost.Editable = true;
		}

		
		private void StartFillEntries()
		{
			this.statusbar.Pop(STATUS_UPDATING);
			this.statusbar.Push(STATUS_UPDATING, "Updating...");
			ThreadStart job = new ThreadStart(this.FillEntries);
	        Thread thread = new Thread(job);
			thread.IsBackground = true;
	        thread.Start();
		}
		
		protected void FillEntries()
		{
			try
			{
				tc.PopulateEntries(entryListStore);
				this.statusbar.Pop(STATUS_UPDATING);
			}
			catch (System.Net.WebException e)
			{
				this.statusbar.Pop(STATUS_UPDATING);
				this.statusbar.Push(STATUS_UPDATING, "Error while retriving updates");
				log.Error("Error while retriving updates", e);
			}
		}
		
		private void RenderEntryIcon (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
		{
			Entry entry = (Entry) model.GetValue (iter, 0);
			string path = entry.Icon;
			if (path != null)
			{
				(cell as Gtk.CellRendererPixbuf).Pixbuf = new Gdk.Pixbuf(path);
			} 
			else
			{
				(cell as Gtk.CellRendererPixbuf).Pixbuf = Gdk.Pixbuf.LoadFromResource("TwitterDefault.png");
			}
		}
	 
		private void RenderEntryText (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
		{
			Entry entry = (Entry) model.GetValue (iter, 0);
			(cell as Gtk.CellRendererText).Markup = "<b>" + GLib.Markup.EscapeText(entry.User) + "</b>\n" + GLib.Markup.EscapeText(entry.Text) + "\n<i>" + GLib.Markup.EscapeText(entry.CreatedAt) + "</i>\n";
		}

		protected virtual void OnMainTreeSizeAllocated (object o, Gtk.SizeAllocatedArgs args)
		{
			textCell.WrapWidth = textColumn.Width - 70;
		}

		protected virtual void OnExitActionActivated (object sender, System.EventArgs e)
		{
			Quit ();
		}
		
		private void Quit()
		{
			int[] windowStatus = new int[4];
			this.GetPosition(out windowStatus[0], out windowStatus[1]);
			this.GetSize(out windowStatus[2], out windowStatus[3]);
			config.windowStatus = windowStatus;
			Application.Quit ();
		}

		protected virtual void OnAboutActionActivated (object sender, System.EventArgs e)
		{
			About abt = new About();
			abt.Run();
			abt.Dispose();
		}

	}
}